package com.kooison.trafficMonitor.crawler;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import com.kooison.crawler.xml.jaxb.model.td.Area;
import com.kooison.crawler.xml.jaxb.model.td.TrafficInfo;

public class XmlCrawler extends BaseCrawler implements ICrawler {

	private static String mXmlSource = null;
	private TrafficInfo mTrafficInfo = null;
	private long mLastModified;
	private static long mTimeDiff = 5 * 60 * 1000;

	@Override
	public TrafficInfo getTrafficInfo() {
		return getTrafficInfo(new String[]{});
	}

	@Override
	public TrafficInfo getTrafficInfo(String area) {
		return getTrafficInfo(new String[]{area});
	}
	
	@Override
	public TrafficInfo getTrafficInfo(String[] areas) {
		TrafficInfo info = new TrafficInfo();
		
		try {
			TrafficInfo tmpInfo = readXml(false);
			if (areas != null && areas.length > 0 && !"".equals(areas[0])) {
				List<Area> l = new ArrayList<Area>();
				for (String area : areas) {
					for (Area a : tmpInfo.getArea()) {
						if (area.equalsIgnoreCase(a.getAreaID())) {
							l.add(a);
							break;
						}
					}
				}
				info.setArea(l);
				info.setLastUpdateTime(tmpInfo.getLastUpdateTime());
			} else {
				info = tmpInfo;
			}
		} catch (Exception e) {
			log.log(Level.WARNING, "Cannot read xml", e);
		}
		return info;
	}

	public XmlCrawler() {
		mXmlSource = mProperties.getProperty("xml_source");
		String refresh_time_in_min = mProperties.getProperty("refresh_time_in_min");
		if (refresh_time_in_min != null) {
			mTimeDiff = Integer.parseInt(refresh_time_in_min) * 60 * 1000;
		}
		log.info("XML Source is [" + mXmlSource + "]");
		log.info("Refresh Time is [" + mTimeDiff + "]");
	}

	public void reload() {
		try {
			readXml(true);
		} catch (Exception e) {
			log.log(Level.WARNING, "Cannot reload xml", e);
		}
	}
	
	private TrafficInfo readXml(boolean reload) throws JAXBException, IOException {
		/*
		Area a1 = new Area();
		a1.setAreaID("1212");
		a1.setAreaName("asdas");
		
		Area a2 = new Area();
		a2.setAreaID("2222");
		a2.setAreaName("aass");
		
		List<Area> l = new ArrayList<Area>();
		l.add(a1);
		l.add(a2);
		
		TrafficInfo info = new TrafficInfo();
		info.setLastUpdateTime("today");
		info.setArea(l);
		
		
		// create JAXB context and instantiate marshaller
		JAXBContext context1 = JAXBContext.newInstance(TrafficInfo.class);
		Marshaller m = context1.createMarshaller();
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		m.marshal(info, System.out);
		*/

		// Check file modified
		URL url = new URL(mXmlSource);
		long accessTime = new Date().getTime();
		// log.info("last modified=" + accessTime + "," + new Date(accessTime));
		// log.info("last modified server=" + mLastModified + "," + new Date(mLastModified));
		long diff = Math.abs(accessTime - mLastModified);
		// log.info("diff=" + diff + "," + new Date(diff));
		if (diff > mTimeDiff || reload) {
			JAXBContext context = JAXBContext.newInstance(TrafficInfo.class);
			Unmarshaller um = context.createUnmarshaller();
			// TrafficInfo trafficInfo = (TrafficInfo) um.unmarshal(new FileReader("C:/WisersDev/HongKongTraffic/src/trafficHK.xml"));
			TrafficInfo trafficInfo = (TrafficInfo) um.unmarshal(new URL(mXmlSource));
			log.info(trafficInfo.toString());
			mTrafficInfo = trafficInfo;
			mLastModified = accessTime;
		}
		return mTrafficInfo;
	}

	public static void main(String[] args) {
		try {
			XmlCrawler c = new XmlCrawler();
			c.readXml(true);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
